#include "CDailyTaskMgr.h"

#include <iostream>
#include <fstream>
#include <vector>
#include "pb_cfg_dailytask.pb.h"
#include "../mainctrl.h"

int CDailyTaskMgr::Init()
{
    int iRet = 0;

    iRet = _stTaskConfig.Init();
    CHECK_RETURN(iRet);

    return 0;
}

int CDailyTaskMgr::LoadConfig(const char* szLogPath)
{
    int iRet = 0;

    if (szLogPath == NULL)
    {
        CT_ERROR(("DailyTask Log Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_dailytask stTaskPBConfig;
    std::fstream stFileInput(szLogPath, std::ios::in | std::ios::binary);
    if (!stTaskPBConfig.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse DailyTaskCfg!"));
        return RET_SYSTEM_FAIL;
    }

    //解析配置文件内容
    CT_TRACE(("dailytask config count %d", stTaskPBConfig.dailytask_config_rows_size()));
    for (int i = 0; i < stTaskPBConfig.dailytask_config_rows_size(); ++i)
    {
        const pb_cfg_dailytask_pb_cfg_dailytask_config_unit& stTaskPBConfigUnit 
            = stTaskPBConfig.dailytask_config_rows(i);

        CDailyTaskConfigData stConfigData;
    
        //任务ID
        stConfigData._iTaskId = (unsigned int)stTaskPBConfigUnit.task_id();
        CT_TRACE(("任务ID %d", stConfigData._iTaskId));
        
        //是否有上限
        stConfigData._bHasCeiling = stTaskPBConfigUnit.has_ceiling()>0 ? true:false;
        //是否可找回
        stConfigData._bFindYesterday = stTaskPBConfigUnit.find_yesterday()>0 ? true:false;

        CT_TRACE(("是否有上限:%d , 是否可找回:%d", stConfigData._bHasCeiling?1:0, stConfigData._bFindYesterday?1:0));

        //任务类型
        stConfigData._iTaskBelong = stTaskPBConfigUnit.task_belong();

        stConfigData._iFinishDestNum = stTaskPBConfigUnit.finish_dest_num();
        stConfigData._iFamilyDestNum = stTaskPBConfigUnit.family_dest_num();
        
        //读取该任务的各vip级别目标次数
        stConfigData._aDailyVipDest.m_iUsedCount = MAX_DAILY_VIP_DEST_CONFIG;
        for (int i2 = 0; i2 < stTaskPBConfig.dailytaskvip_config_rows_size(); ++i2)
        {
            const pb_cfg_dailytask_pb_cfg_dailytaskvip_config_unit& stTaskPBConfigUnit 
                = stTaskPBConfig.dailytaskvip_config_rows(i2);

            int iVipTaskId = (unsigned int)stTaskPBConfigUnit.task_id();
            if( iVipTaskId==stConfigData._iTaskId )
            {
                DailyVipDest sDVipDest;

                sDVipDest.iTaskId = iVipTaskId;
                sDVipDest.iVipLevel = (unsigned int)stTaskPBConfigUnit.vip_level();
                sDVipDest.iDestNum = (unsigned int)stTaskPBConfigUnit.vip_dest_num();
                stConfigData._aDailyVipDest[sDVipDest.iVipLevel] = sDVipDest;
            }
        }

        stConfigData._bHasConfig = true;
        iRet = this->_stTaskConfig.AddTaskConfig( stConfigData ); 
        CHECK_RETURN(iRet);
    }

    CT_TRACE(("dailytask class award config count %d", stTaskPBConfig.classaward_config_rows_size()));
    for (int i = 0; i < stTaskPBConfig.classaward_config_rows_size(); ++i)
    {
        const pb_cfg_dailytask_pb_cfg_classaward_config_unit & stTaskPBConfigUnit 
                 = stTaskPBConfig.classaward_config_rows(i);

        //任务类型
        if (stTaskPBConfigUnit.task_belong() != DAILY_TASK_CLASSTYPE_NONE)
        {
            CDailyTaskClassAwardConfigData stConfigData;

            //任务类型
            stConfigData._iTaskBelongType = stTaskPBConfigUnit.task_belong();
            //奖励物品类型
            stConfigData._iAwardItemType = stTaskPBConfigUnit.award_item_type();
            //奖励物品标识,此标识要做特殊处理
            stConfigData._iAwardItemId = stTaskPBConfigUnit.award_item_id();

            //普通用户奖励数量
            stConfigData._iAwardNumCommon = stTaskPBConfigUnit.award_num_common();

            //vip
            stConfigData._iAwardNumVip1   = stTaskPBConfigUnit.award_num_vip1();
            stConfigData._iAwardNumVip4   = stTaskPBConfigUnit.award_num_vip4();
            stConfigData._iAwardNumVip7   = stTaskPBConfigUnit.award_num_vip7();
            stConfigData._iAwardNumVip10  = stTaskPBConfigUnit.award_num_vip10();

            stConfigData._bHasConfig = true;
            iRet = this->_stTaskConfig.AddClassAwardConfig( stConfigData );
            CHECK_RETURN(iRet);
        }
    }

    CT_TRACE(("dailytask tbox award config count %d", stTaskPBConfig.tboxaward_config_rows_size()));
    for (int i = 0; i < stTaskPBConfig.tboxaward_config_rows_size(); ++i)
    {
        const pb_cfg_dailytask_pb_cfg_tboxaward_config_unit & stTaskPBConfigUnit
             = stTaskPBConfig.tboxaward_config_rows(i);

        CDailyTaskTboxAwardConfigData stConfigData;

        stConfigData._iTboxId = stTaskPBConfigUnit.tbox_id();
        stConfigData._ineed_liveness = stTaskPBConfigUnit.need_liveness();

        if( stTaskPBConfigUnit.award_item_type1() != 0 )
        {
            CDailyTaskTboxAwardConfigData::TBoxAward tba;
            tba.iAwardItemType = stTaskPBConfigUnit.award_item_type1();
            tba.iAwardItemId   = stTaskPBConfigUnit.award_item_id1();
            tba.iAwardNum      = stTaskPBConfigUnit.award_num1();

            stConfigData._aTboxAwards.AddOneItem( tba );

            CT_TRACE(("宝箱奖励%d: 类型:%d,id:%d, 数量:%d", i, tba.iAwardItemType, tba.iAwardItemId, tba.iAwardNum));

            if( stTaskPBConfigUnit.award_item_type2() != 0 )
            {
                tba.iAwardItemType = stTaskPBConfigUnit.award_item_type2();
                tba.iAwardItemId   = stTaskPBConfigUnit.award_item_id2();
                tba.iAwardNum      = stTaskPBConfigUnit.award_num2();

                stConfigData._aTboxAwards.AddOneItem( tba );

                CT_TRACE(("宝箱奖励%d: 类型:%d,id:%d, 数量:%d", i, tba.iAwardItemType, tba.iAwardItemId, tba.iAwardNum));

                if( stTaskPBConfigUnit.award_item_type3() != 0 )
                {
                    tba.iAwardItemType = stTaskPBConfigUnit.award_item_type3();
                    tba.iAwardItemId   = stTaskPBConfigUnit.award_item_id3();
                    tba.iAwardNum      = stTaskPBConfigUnit.award_num3();

                    stConfigData._aTboxAwards.AddOneItem( tba );

                    CT_TRACE(("宝箱奖励%d: 类型:%d,id:%d, 数量:%d", i, tba.iAwardItemType, tba.iAwardItemId, tba.iAwardNum));

                    if( stTaskPBConfigUnit.award_item_type4() != 0 )
                    {
                        tba.iAwardItemType = stTaskPBConfigUnit.award_item_type4();
                        tba.iAwardItemId   = stTaskPBConfigUnit.award_item_id4();
                        tba.iAwardNum      = stTaskPBConfigUnit.award_num4();

                        stConfigData._aTboxAwards.AddOneItem( tba );

                        CT_TRACE(("宝箱奖励%d: 类型:%d,id:%d, 数量:%d", i, tba.iAwardItemType, tba.iAwardItemId, tba.iAwardNum));
                    }
                }
            }
        }

        stConfigData._bHasConfig = true;
        iRet = this->_stTaskConfig.AddTboxAwardConfig( stConfigData );
        CHECK_RETURN(iRet);
    }

    //小秘书购买配置
    for (int i = 0; i < stTaskPBConfig.secretary_config_rows_size(); ++i)
    {
        const pb_cfg_dailytask_pb_cfg_secretary_config_unit & stTaskPBConfigUnit 
                 = stTaskPBConfig.secretary_config_rows(i);

        CSecretaryPayConfigData stConfigData;

        //小秘书形象id
        stConfigData._iStyleId = stTaskPBConfigUnit.style_id();
        stConfigData._iNeedGold = stTaskPBConfigUnit.need_gold();
        stConfigData._iDailyAddLiveness = stTaskPBConfigUnit.add_liveness();

        stConfigData._bHasConfig = true;
        iRet = this->_stTaskConfig.AddSecretaryPayConfig( stConfigData );

        CHECK_RETURN(iRet);
    }

    //小秘书等级配置
    for (int i = 0; i < stTaskPBConfig.secretary_level_rows_size(); ++i)
    {
        const pb_cfg_dailytask_pb_cfg_secretary_level_unit & stTaskPBConfigUnit 
                 = stTaskPBConfig.secretary_level_rows(i);

        CSecretaryLevelConfigData stConfigData;

        //小秘书等级
        stConfigData._iLevel = stTaskPBConfigUnit.level();
        stConfigData._iNeedIntimacy = stTaskPBConfigUnit.need_intimacy();
        stConfigData._iPrestigeAdd = stTaskPBConfigUnit.prestige_add();
        stConfigData._iSilverAdd = stTaskPBConfigUnit.silver_add();

        stConfigData._bHasConfig = true;
        iRet = this->_stTaskConfig.AddSecretaryLevelConfig( stConfigData );

        CHECK_RETURN(iRet);
    }

    return 0;
}

int CDailyTaskMgr::GetTaskConfig(int iTaskID, CDailyTaskConfigData& stTaskConfigData)
{
    return _stTaskConfig.GetTaskConfig(iTaskID, stTaskConfigData);
}

int CDailyTaskMgr::GetDailyTaskCnfSize()
{
    return _stTaskConfig._astDailyTaskConfigs.Size();
}

CDailyTaskConfigData& CDailyTaskMgr::GetDailyTaskConfig(int iIndex)
{
    return _stTaskConfig._astDailyTaskConfigs[iIndex];
}

int CDailyTaskMgr::ValidTaskId(unsigned int iTaskID)
{
    int iRet = 0;
    CDailyTaskConfigData stData;

    iRet = this->_stTaskConfig.GetTaskConfig(iTaskID, stData);
    CHECK_RETURN(iRet);

    return 0;
}

int CDailyTaskMgr::CheckHasCeiling(unsigned int iTaskID)
{
    int iRet = 0;
    CDailyTaskConfigData stData;

    iRet = this->_stTaskConfig.GetTaskConfig(iTaskID, stData);
    CHECK_RETURN(iRet);
    
    if( !stData._bHasCeiling )
    {
        return -1;
    }

    return 0;
}

/*
Return value:
    0:successful
iTaskCeilingCount:
    目标次数
bHasCeiling:
    是否有上限
*/
int CDailyTaskMgr::CheckTaskCeiling(CUserDailyTask& stUserTask, unsigned int &iTaskID, unsigned int & iTaskCeilingCount, bool& bHasCeiling)
{
    int iRet = 0;
    CDailyTaskConfigData stData;
    int iHighFinishCounts = 0; //上限次数

    iRet = this->_stTaskConfig.GetTaskConfig(iTaskID, stData);
    CHECK_RETURN(iRet);

    //有上限
    bHasCeiling = stData._bHasCeiling;

    //目标次数应该不考虑上限
    //家族的数据
    bool bIsClanUser = false;
    int iClanIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(stUserTask.GetUserGid());
    if (iClanIndex >= 0)
    {
        bIsClanUser = true;
    }

    //取得用户是否vip
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stUserTask.GetUserGid());
    if (iIndex < 0)
    {
        iRet = ERROR_NO_SUCH_USER;
        CT_ERROR(("user %u not in hash", stUserTask.GetUserGid()));
    }
    short isVipLevel = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex]._chVipLevel;
    if( isVipLevel<0 )
    {
        CT_ERROR(("user %u is invalid vip", stUserTask.GetUserGid()));
        return ERROR_INVALID_VIP; 
    }

    if( isVipLevel==CONST_VIP_HIGH_LEVEL0 )
    {
        if( bIsClanUser )
        {
            iHighFinishCounts = stData._iFamilyDestNum;
        }
        else
        {
            iHighFinishCounts = stData._iFinishDestNum;
        }
    }
    else
    {
        //无论普通用户或是家族用户都使用vip数据
        iHighFinishCounts = stData._aDailyVipDest[isVipLevel].iDestNum;
    }

    iTaskCeilingCount = iHighFinishCounts;

    return 0;
}

//试试手运
int CDailyTaskMgr::DiyLuckDoubleAwardBox(CUserDailyTask& stUserTask, int& iFucklyBoxId)
{
    int iRet = 0;

    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stUserTask.GetUserGid());
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    //是否达到20级
    if( stPlayerBaseInfo._shLevel<CONST_DIY_DOUBLE_AWARD_LEVEL )
    {
        return ERROR_LOW_LEVEL_DIY_DOUBLE_AWARD;
    }

    stUserTask.CheckDailyTaskUpdate();

    iRet = stUserTask.DiyLuckDoubleAwardBox( iFucklyBoxId );

    return iRet;
}

int CDailyTaskMgr::OpenTBox(CUserDailyTask& stUserTask, int iTBox, MsgAnsOpenTbox& stAns)
{
    int iRet = 0;

    stUserTask.CheckDailyTaskUpdate();

    if( iTBox>CONST_TASK_CLASS_STATUS && iTBox<=CONST_TASK_CLASS_STATUS+DAILY_TASK_CLASSTYPE_STRONG )
    { //开启类型宝箱
        int iTBoxClassTypeId = iTBox - CONST_TASK_CLASS_STATUS;
        iRet = this->OpenClassTBox( stUserTask, iTBoxClassTypeId, stAns );
    }
    else //开启宝箱
    {
        iRet = this->OpenTBoxOne( stUserTask, iTBox, stAns );
    }

    return iRet;
}

//开启类型宝箱
int CDailyTaskMgr::OpenClassTBox(CUserDailyTask& stUserTask, int iTBoxClassTypeId, MsgAnsOpenTbox& stAns)
{
    int iRet = 0;

    //检查宝箱id
    CDailyTaskClassAwardConfigData stData;
    iRet = this->_stTaskConfig.GetClassAwardConfig((unsigned int)iTBoxClassTypeId, stData);
    CHECK_RETURN(iRet);

    //检查是否可开启此类型宝箱
    int iClassTBoxStatus = stUserTask.GetClassTBoxStatusWithId( iTBoxClassTypeId );
    if( iClassTBoxStatus==CONST_TBOX_CANOT_OPEN )
    {
        return ERROR_TBOX_CANOT_OPEN;
    }
    else if( iClassTBoxStatus==CONST_TBOX_OPENED ) //检查是否已经开启过
    {
        return ERROR_TBOX_OPENED;
    }


    //取得用户是否vip
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stUserTask.GetUserGid());
    if (iIndex < 0)
    {
        iRet = ERROR_NO_SUCH_USER;
        CT_ERROR(("user %u not in hash", stUserTask.GetUserGid()));
    }
    short isVipLevel = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex]._chVipLevel;
    int iAwardNums = 0;
    if( isVipLevel==CONST_VIP_HIGH_LEVEL0 )
    {
        iAwardNums = stData._iAwardNumCommon;
    }
    else if( isVipLevel<=CONST_VIP_HIGH_LEVEL1 )
    {
        iAwardNums = stData._iAwardNumVip1;
    }
    else if( isVipLevel<=CONST_VIP_HIGH_LEVEL2 )
    {
        iAwardNums = stData._iAwardNumVip4;
    }
    else if( isVipLevel<=CONST_VIP_HIGH_LEVEL3 )
    {
        iAwardNums = stData._iAwardNumVip7;
    }
    else if( isVipLevel>=CONST_VIP_HIGH_LEVEL4 )
    {
        iAwardNums = stData._iAwardNumVip10;
    }

    stData._iAwardNumCommon = iAwardNums;

    //可以开启CONST_TBOX_CAN_OPEN
    iRet = TriggerClassTaskAward(stUserTask, stData, stAns);
    CHECK_RETURN(iRet);

    stUserTask.OpenClassTBoxWithId( iTBoxClassTypeId );

    return 0;
}

//开启宝箱
int CDailyTaskMgr::OpenTBoxOne(CUserDailyTask& stUserTask, int iTBox, MsgAnsOpenTbox& stAns)
{
    int iRet = 0;

    //检查宝箱id
    CDailyTaskTboxAwardConfigData stData;
    iRet = this->_stTaskConfig.GetTboxAwardConfig((unsigned int)iTBox, stData);
    CHECK_RETURN(iRet);
    
    //检查活跃度
    int iCurLiveness = stUserTask.GetCurLiveness();
    if( iCurLiveness >= stData._ineed_liveness )//达到活跃度条件
    {
        //检查是否已经开启过
        int iTBoxStatus = stUserTask.GetTBoxStatusWithId( iTBox );
        if( iTBoxStatus==CONST_TBOX_CANOT_OPEN || iTBoxStatus==(CONST_DOUBLE_AWARD_BASE+CONST_TBOX_CANOT_OPEN) )
        {
            return ERROR_TBOX_CANOT_OPEN;
        }
        else if( iTBoxStatus==CONST_TBOX_OPENED || iTBoxStatus==(CONST_DOUBLE_AWARD_BASE+CONST_TBOX_OPENED) )
        {
            return ERROR_TBOX_OPENED;
        }
        else //CONST_TBOX_CAN_OPEN
        {
            //发放宝箱奖励,需要考虑亲密度等级加成奖励
            //需要考虑双倍宝箱奖励
            bool bDoubleAward = false;
            if( iTBoxStatus>=CONST_DOUBLE_AWARD_BASE )
            {
                bDoubleAward = true;
            }
            iRet = TriggerTaskAward(stUserTask, stData, stAns, bDoubleAward);
            CHECK_RETURN(iRet);

            stUserTask.OpenTBoxWithId( iTBox );

            //检查亲密度升级
            CheckIntimacyUpdate(stUserTask);
        }
    }

    return 0;
}

int CDailyTaskMgr::CheckIntimacyUpdate(CUserDailyTask& stUserTask)
{
    int iRet = 0;
    int iNewSecretaryLevel = 0; 
    CSecretaryLevelConfigData stData;
    int iIntimacyValue = stUserTask.GetIntimacyValue();

    for( int i=0; i<this->_stTaskConfig._astSecretaryLevelConfigs.Size(); ++i )
    {
        iRet = this->_stTaskConfig.GetSecretaryLevelConfig(i+1, stData);
        if( iRet==RET_OK )
        {
            if( iIntimacyValue<stData._iNeedIntimacy )
            {
                iNewSecretaryLevel = i; 
                break;
            }
            else
            {
                iNewSecretaryLevel = i + 1;
            }
        }
        else
        {
            break;
        }
    }

    if( iNewSecretaryLevel!=0 )
    {
        stUserTask.SetIntimacyLevel( iNewSecretaryLevel );
    }

    return iRet;
}

int CDailyTaskMgr::FindYesterdayTask(CUserDailyTask& stUserTask, CPlayerBaseInfo& stPlayerBaseInfo, unsigned int iTaskId)
{
    int iRet = 0;
    //检查是否可找回
    CDailyTaskConfigData stTaskConfigData;
    iRet = this->GetTaskConfig(iTaskId, stTaskConfigData);
    CHECK_RETURN(iRet);

    stUserTask.CheckDailyTaskUpdate();

    if( !stTaskConfigData._bFindYesterday )//当前任务不能找回
    {
        return ERROR_DAILY_TASK_CANOT_FIND;
    }

    //检查是否已经完成当天任务
    unsigned int iTaskCeilingCount = 0;
    bool bHasCeiling = false;
    iRet = CheckTaskCeiling( stUserTask, iTaskId, iTaskCeilingCount, bHasCeiling);
    CHECK_RETURN(iRet);
    unsigned int iTaskCounts = stUserTask.GetFinishCountsWithId( iTaskId );
    if( iTaskCounts<iTaskCeilingCount )
    {
        return ERROR_NOT_FINISH_CUR_DAILYTASK;//还没有完成当天任务，不可找回
    }

    //检查昨天没有做过此任务
    int iTaskYesCount = stUserTask.GetYesterdayFinishId( iTaskId );
    if( iTaskYesCount > 0 )
    {
        CT_WARNING(("Find yesterday taskid:%d, yesterday has finish this task %d counts", iTaskId, iTaskYesCount));
        return ERROR_DAILY_TASK_CANOT_FIND;
    }

    //扣费
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_40, DAILY_TASK_FIND_YES_TASK_NEED_GOLD); 
    CHECK_RETURN(iRet);

    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerBaseInfo._uiGID, NOTIFY_USER_MONEY);

    //so, this task can find yesterday 
    iRet = stUserTask.FindYesterdayTask(iTaskId);

    return iRet;
}

int CDailyTaskMgr::InitForNewUser(CDailyTaskUserData & stUserTaskData)
{
    int iRet = 0;
    //宝箱初始化
    stUserTaskData._aOpenedTBox.m_iUsedCount = this->_stTaskConfig._astDailyTaskTboxConfigs.Size();
    for( int i=0; i<this->_stTaskConfig._astDailyTaskTboxConfigs.Size(); ++i )
    {
        //if( i==0 )continue;//宝箱从序号1开始
        stUserTaskData._aOpenedTBox[i] = CONST_TBOX_CANOT_OPEN;//当前不可开启
    }

    //类型奖励
    stUserTaskData._aTaskClassStatus.m_iUsedCount = MAX_DAILY_TASK_CLASS_CONFIG;
    for( int i=1; i<MAX_DAILY_TASK_CLASS_CONFIG; ++i )
    {
        stUserTaskData._aTaskClassStatus[i] = CONST_TBOX_CANOT_OPEN;//当前不可开启
    }

    for( int i=0; i<this->_stTaskConfig._astDailyTaskConfigs.Size(); ++i )
    {
        CDTaskStatus sCDT;

        sCDT.iTaskId = this->_stTaskConfig._astDailyTaskConfigs[i]._iTaskId;
        sCDT.iCount = 0;
        sCDT._iTaskClassTypeId = this->_stTaskConfig._astDailyTaskConfigs[i]._iTaskBelong;
        sCDT._stYesterdayTaskFinish.SetDefault(0);
        sCDT._iFindYesterdayOp = 0;

        stUserTaskData._aDailyTaskUserClass.AddOneItem( sCDT );
    }

    stUserTaskData._stDailyLivess.SetDefault( 1 ); //小秘书每日增加活跃度次数
    stUserTaskData._stSecretary._cStyle = SECRETARY_TYPE_COMMON; //默认为普通小秘书
    stUserTaskData._stSecretary._iLevel = 0; //亲密度等级0级
    stUserTaskData._stSecretary._iIntimacy = 0; //累计亲密度
    stUserTaskData._stSecretary._iLiveTime = 0; //当前小秘书有效期, 0为无限期

    return iRet;
}

int CDailyTaskMgr::GetTaskList(CUserDailyTask& stUserTask, MsgAnsGetDailyTask& stTaskListAns)
{
    int iRet = 0;

    stUserTask.CheckDailyTaskUpdate();

    stTaskListAns.set_liveness( stUserTask.GetLiveValuer() );

    CDailyTaskUserData stUserTaskData;
    iRet = stUserTask.GetData(stUserTaskData);
    if (iRet != RET_OK)
    {
        CT_WARNING(("%u", stUserTask.GetUserGid()));
        return iRet;
    }

    //宝箱的奖励
    for( int i=0; i<stUserTaskData._aOpenedTBox.Size(); ++i )
    {
        MsgOneTBox * mOneTBox = stTaskListAns.add_tboxs();
        mOneTBox->set_tbox_id(i+1);
        mOneTBox->set_status(stUserTaskData._aOpenedTBox[i]); //0:当前不可开启, 1:可开启, 2:已经开启
    }

    //类型奖励
    for( int i=1; i<MAX_DAILY_TASK_CLASS_CONFIG; ++i )
    {
        MsgOneTBox * mOneTBox = stTaskListAns.add_tboxs();
        mOneTBox->set_tbox_id(i+CONST_TASK_CLASS_STATUS);
        mOneTBox->set_status(stUserTaskData._aTaskClassStatus[i]); //0:当前不可开启, 1:可开启, 2:已经开启
    }

    for( int i=0; i<stUserTaskData._aDailyTaskUserClass.Size(); ++i )
    {
        unsigned int iTaskId = stUserTaskData._aDailyTaskUserClass[i].iTaskId;
        //查询任务配置
        CDailyTaskConfigData stData;
        unsigned int iTaskCeilingCount = 0;
        iRet = this->_stTaskConfig.GetTaskConfig( iTaskId, stData );
        if( iRet!=0 )
        {
            CT_TRACE(("查询每日任务配置出错,taskid:%d", iTaskId));
        }

        //目标次数
        bool bHasCeiling = false;
        iRet = this->CheckTaskCeiling(stUserTask, iTaskId, iTaskCeilingCount, bHasCeiling);
        if( iRet!=0 )
        {
            CT_TRACE(("查询每日任务配置出错"));
        }
        if( iTaskCeilingCount==0 )
        {
            CT_TRACE(("查询%u每日任务配置%d为空任务，不显示", stUserTask.GetUserGid(), iTaskId));
            continue;
        }

        MsgOneDailyTask * mOneDailyTask = stTaskListAns.add_tasks();

        mOneDailyTask->set_task_type( stUserTaskData._aDailyTaskUserClass[i]._iTaskClassTypeId);

        mOneDailyTask->set_task_id( stUserTaskData._aDailyTaskUserClass[i].iTaskId);
        mOneDailyTask->set_finish_counts(stUserTaskData._aDailyTaskUserClass[i].iCount);

                //设置任务完成状态
        if( (unsigned int)stUserTaskData._aDailyTaskUserClass[i].iCount>=iTaskCeilingCount )
        {
            mOneDailyTask->set_is_finish(1);
        }
        else
        {
            mOneDailyTask->set_is_finish(0);
        }
        
        //设置可找回,找回必须是当天的任务完成之后，才能找回昨天未做的任务
        //检查是否完成当前的任务,并且昨天的未进行该任务
        if( stData._bFindYesterday )
        {
            //检查昨天没有做过此任务
            int iTaskYesCount = stUserTaskData._aDailyTaskUserClass[i]._stYesterdayTaskFinish.Get(CMainCtrl::m_pstMain->m_iNow-86400);
            if( iTaskYesCount > 0 )
            {
                //if( stUserTaskData._aDailyTaskUserClass[i]._iFindYesterdayOp>0 )
                mOneDailyTask->set_can_find_yesterday(0);
            }
            else
            {
                if( (unsigned int)stUserTaskData._aDailyTaskUserClass[i].iCount>=iTaskCeilingCount )
                {
                    mOneDailyTask->set_can_find_yesterday(1);
                }
            }
        }
        else
        {
            mOneDailyTask->set_can_find_yesterday(0);
        }

        mOneDailyTask->set_high_count(iTaskCeilingCount); //目标次数
        if( stData._bHasCeiling )//有上限 
        {
            mOneDailyTask->set_has_ceiling(1);
        }
        else
        {
            mOneDailyTask->set_has_ceiling(0);
        }
    }

    //设置小秘书数据
    MsgSecretary * msgSecretary = stTaskListAns.mutable_secretary();
    msgSecretary->set_style_id( stUserTaskData._stSecretary._cStyle );
    msgSecretary->set_level( stUserTaskData._stSecretary._iLevel );
    msgSecretary->set_intimacy( stUserTaskData._stSecretary._iIntimacy );
    msgSecretary->set_livetime( stUserTaskData._stSecretary._iLiveTime );

    return iRet;
}

void CDailyTaskMgr::SendTaskInfoToFront(CUserDailyTask& stUserTask)
{
    PBMsgHead stMsgHead;
    stMsgHead.set_time(CMainCtrl::m_pstMain->m_iNow);
    stMsgHead.set_msgact(0);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    stMsgHead.set_msgid(ID_MAIN_GET_DAILY_TASK);
    stMsgHead.set_msgret(RET_OK);

    MsgAnsGetDailyTask stAns;
    GetTaskList(stUserTask, stAns);

    CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
    CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead, CMainCtrl::m_pstMain->m_stEncodeBuf);
    CMainCtrl::m_pstMain->EncodePBMsg(stAns, CMainCtrl::m_pstMain->m_stEncodeBuf);
    CMainCtrl::m_pstMain->NotifyOnlineUser(stUserTask.GetUserGid(), CMainCtrl::m_pstMain->m_stEncodeBuf);
}

int CDailyTaskMgr::TriggerTaskFinish(CUserDailyTask& stUserTask, unsigned int iTaskID, int iCount)
{
    if (iCount <= 0)
    {
        return 0;
    }
    
    int iRet = 0;
    unsigned int iTaskCeilingCount = 0;

    stUserTask.CheckDailyTaskUpdate();

    CT_TRACE(("触发完成一个任务"));
    //验证是否存在这个任务id
    iRet = this->ValidTaskId( iTaskID );
    CHECK_RETURN(iRet);

    bool bHasCeiling = false;
    iRet = this->CheckTaskCeiling(stUserTask, iTaskID, iTaskCeilingCount, bHasCeiling);
    CHECK_RETURN(iRet);

    //查询当前已经完成次数
    unsigned int iAlreadyCounts = stUserTask.GetCurrentFinishCounts( iTaskID );

    //根据任务上限配置检查是否有上限
    if( bHasCeiling )// 有上限
    {
        if( iAlreadyCounts>=iTaskCeilingCount )
        {
            CT_TRACE(("dailytask 当前任务有上限:%d已经完成目标次数", iTaskID));
            return ERROR_DTASK_EXCEED_CEIL;
        }
    }

    //到这里没有上限或者有上限但没有完成目标次数可以继续做任务获取活跃度
    iRet = stUserTask.TriggerTaskFinish( iTaskID, iCount );
    CHECK_RETURN(iRet);

    iAlreadyCounts = stUserTask.GetCurrentFinishCounts( iTaskID );
    if( iAlreadyCounts>=iTaskCeilingCount )
    {
        UpdateClassTypeFinish(stUserTask, iTaskID);
    }

    //推送前端
    SendTaskInfoToFront(stUserTask);

    return iRet;
}

//触发改变类型任务的宝箱状态
int CDailyTaskMgr::UpdateClassTypeFinish(CUserDailyTask& stUserTask, unsigned int iTaskID)
{
    int iRet = 0;
    CDailyTaskConfigData stData;

    iRet = this->_stTaskConfig.GetTaskConfig(iTaskID, stData);
    CHECK_RETURN(iRet);
    
    //检查所有同一类型的任务是否完成
    iRet = stUserTask.UpdateClassTypeFinish( stData._iTaskBelong );

    return iRet;
}

int CDailyTaskMgr::GMSetDailyTask(CUserDailyTask& stUserTask, int iNewLiveness)
{
    int iRet = 0;

    int iTBoxId = 0;

    iTBoxId = this->GetMaxTBoxIdWIthLiveness(iNewLiveness);

    iRet = stUserTask.GMSetDailyTask(iNewLiveness, iTBoxId);

    return iRet;
}

int CDailyTaskMgr::GetSecretaryPayConfig(int _iStyleId, CSecretaryPayConfigData& stData)
{
    return this->_stTaskConfig.GetSecretaryPayConfig(_iStyleId, stData);
}

//购买小秘书
int CDailyTaskMgr::BuySecretaryStyle(CUserDailyTask& stUserTask, int iSecretaryStyle)
{
    int iRet = 0;
    //检查需要金币
    CSecretaryPayConfigData stData;
    iRet = this->_stTaskConfig.GetSecretaryPayConfig(iSecretaryStyle, stData);
    CHECK_RETURN(iRet);
    
    stUserTask.CheckDailyTaskUpdate();

    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stUserTask.GetUserGid());
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    if( stPlayerBaseInfo._iGold < stData._iNeedGold )
    {
        return ERROR_SECRETARY_NOT_ENOUGH_GOLD;
    }

    iRet = stUserTask.BuySecretaryStyle( iSecretaryStyle, stData._iNeedGold );

    return iRet;
}

int CDailyTaskMgr::TriggerClassTaskAward(CUserDailyTask& stUserTask, CDailyTaskClassAwardConfigData& curTaskCfgData, MsgAnsOpenTbox& stAns)
{
	int iRet = 0;
	CDropItem stDropItem;

	iRet = stUserTask.GetTaskClassAwardItems(curTaskCfgData, stDropItem);
	if (iRet != RET_OK)
	{
	    CT_WARNING(("CDailyTaskMgr::GetTaskClassAwardItems:get award items fail-%d", iRet));
        return iRet;
	}

    //assign award items to user
    stDropItem.SetOssModule(OSS_MODULE_DAYTASK);
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, stUserTask.GetUserGid(), stDropItem);
    CHECK_RETURN(iRet);

    //显示给前台 返回奖励信息
    stDropItem.GetPBMsg(stUserTask._uiGID, *(stAns.mutable_awards()));

	return RET_OK;
}

int CDailyTaskMgr::TriggerTaskAward(CUserDailyTask& stUserTask, CDailyTaskTboxAwardConfigData& curTaskCfgData, MsgAnsOpenTbox& stAns, bool bDoubleAward)
{
	int iRet = 0;
	CDropItem stDropItem;

    CSecretaryLevelConfigData curLevelCfgData;

    iRet = this->_stTaskConfig.GetSecretaryLevelConfig(stUserTask.GetSecretaryLevel(), curLevelCfgData);
    CHECK_RETURN(iRet);

	iRet = stUserTask.GetTaskAwardItems(curTaskCfgData, curLevelCfgData, stDropItem, bDoubleAward);
	if (iRet != RET_OK)
	{
	    CT_WARNING(("CDailyTaskMgr::TriggerTaskAward:get award items fail-%d", iRet));
        return iRet;
	}

	//assign award items to user
    stDropItem.SetOssModule(OSS_MODULE_DAYTASK);
	iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, stUserTask.GetUserGid(), stDropItem);
    CHECK_RETURN(iRet);

    //显示给前台 返回奖励信息
    stDropItem.GetPBMsg(stUserTask._uiGID, *(stAns.mutable_awards()));

	return iRet;
}

int CDailyTaskMgr::GetMaxTBoxIdWIthLiveness(int iNewLiveness) 
{
    int iTBoxId = 0;
    CDailyTaskTboxAwardConfigData stData;
    for( int i=0; i<this->_stTaskConfig._astDailyTaskTboxConfigs.Size(); ++i )
    {
        this->_stTaskConfig.GetTboxAwardConfig(i+1, stData);
        if( iNewLiveness<stData._ineed_liveness )
        {
            iTBoxId = i+1;
            break;
        }
    }
    if( iTBoxId==0 )
    {
        iTBoxId = this->_stTaskConfig._astDailyTaskTboxConfigs.Size()+1;
    }

    return iTBoxId;
}

/*
int CDailyTaskMgr::GMSetTaskFinished(int iTaskId, CUserDailyTask& stUserTask)
{
    if( iTaskId<=0 )
    {
        CT_TRACE(("GM set task finish:arguments error%d", iTaskId));
        return -1;
    }

    int iRet = 0;
    CTaskID stTaskID;
    stTaskID._uiBranchID = (unsigned int)iTaskId / TASK_CONFIG_ID_MOD;
    stTaskID._uiTaskID = (unsigned int)iTaskId % TASK_CONFIG_ID_MOD;

    stUserTask.GMSetTaskFinished( stTaskID );

    CTaskConfigData stConfigData;
    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    for (int i = 0; i < stConfigData._astFollowTasks.Size(); ++i)
    {
        CT_TRACE(("打开后续任务 %d", i));

        CTaskConfigData stFollowTaskConfigData;
        iRet = _stTaskConfig.GetConfig(stConfigData._astFollowTasks[i], stFollowTaskConfigData);
        CHECK_RETURN(iRet);
        iRet = this->GMAddFollowTasks( stFollowTaskConfigData, stUserTask );
*/
        /* if (!stFollowTaskConfigData.NeedOpen())
        {
            iRet = AcceptTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        }
        else
        {
            iRet = WaitForOpenTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        } */
 /*   }

    iRet = stUserTask.UpdateTaskList2Front();

    return iRet;
}

int CDailyTaskMgr::GMAddFollowTasks(CTaskConfigData& stFollowTaskConfigData, CUserDailyTask& stUserTask)
{
    int iRet = 0;        
    //Add follow tasks
    CValidTask stValidTask(stFollowTaskConfigData._stTaskID);
    for (int i = 0; i < stFollowTaskConfigData._astFinishConds.Size(); ++i)
    {
        CTaskTargetStat stStat;
        stStat._bIsReachCond = false;
        stStat._stTaskID = stFollowTaskConfigData._stTaskID;
        stStat._stCond = stFollowTaskConfigData._astFinishConds[i];
        stStat._stNowStat._ucCond = stStat._stCond._ucCond;
        stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
        stStat._stNowStat._iCondData2 = 0;

        stValidTask._astTargetStats.AddOneItem(stStat);
    }

    if (stFollowTaskConfigData._astFinishConds.Size() > 0)
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_NORMAIL;
    }
    else
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_FINISH;
    }

    iRet = stUserTask.AddValidTaskData(stValidTask);
    CHECK_RETURN(iRet);

    return 0;
}

*/

